using AnimCollections;
using DA.AnimGraph;
using System.Collections.Generic;

namespace DA.AnimGraph.Editor {
    public class PreviewManager {

        private readonly AGEContext context;
        public string previewTargetName { get; private set; }

        public AGEPreviewPlayer player;
        private Dictionary<string, ulong> bbAddr;
        private Blackboard blackboard;

        public PreviewManager(AGEContext context) {
            this.context = context;
            previewTargetName = null;
        }

        public void ReGetPlayersInScene() {
            AGEGlobal.GetInstance().preview.GetPlayersInScene();
        }

        public List<AGEPreviewPlayer> GetPreviewPlayerList() {
            return AGEGlobal.GetInstance().preview.GetPreviewPlayerList();
        }

        public void OnDisable() {
            StopPreview();
            previewTargetName = null;
        }
        public void SetPreviewTarget(string objName) {
            D.A(player == null, "预览时不允许更改");
            previewTargetName = objName;
        }

        public void TogglePreview() {
            if (player == null) StartPreview();
            else StopPreview();
        }

        public void StartPreview() {
            if (previewTargetName == null) return;
            if (player != null) {
                StopPreview();
            }

            var agpAsset = context.ExportAgpAsset();
            D.A(agpAsset != null, "无法导出agpAsset");
            var candidatePlayer = AGEGlobal.GetInstance().preview.GetPlayer(previewTargetName);
            if (candidatePlayer == null) {
                D.E("[preview] 无法找到目标对象");
                return;
            }

            // bb
            var bbInfo = context.GetBlackboardInfo();
            var dbb = new DynamicBlackboard(bbInfo.Count);
            var bb = new Blackboard(bbInfo.Count);
            bbAddr = new Dictionary<string, ulong>(bbInfo.Count);
            bb.SetBaseAddress(dbb.baseAddr);
            foreach (var info in bbInfo) {
                if (dbb.isFull) {
                    D.Exception("DynamicBlackboard 过量分配变量，检查空间为什么不够");
                }
                var addr = dbb.Allocate();
                bb.BindFieldByAddress(info.Key, addr);
                bbAddr[info.Key] = addr;
            }
            candidatePlayer.StartPreview(agpAsset, context.resourceManager.DumpToDict(), dbb, bb, bbInfo);

            player = candidatePlayer;
            // bb.Dispose();
            blackboard = bb;
            context.SetMode(AGEMode.Preview);
        }
        public void StopPreview() {
            if (player == null) return;
            player.StopPreview();
            player = null;
            context.SetMode(AGEMode.Edit);
        }

        public T GetBBValue<T>(string name) where T : unmanaged {
            T value = default;
            blackboard.GetValue(name, ref value);
            return value;
        }
        public void SetBBValue<T>(string name, T v) where T : unmanaged {
            blackboard.SetValue(name, v);
        }
    }
}
